package cn.zvo.translate.tcdn.admin.controller;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.xnx3.DateUtil;
import com.xnx3.Log;
import com.xnx3.j2ee.controller.BaseController;
import com.xnx3.j2ee.service.SqlCacheService;
import com.xnx3.j2ee.service.SqlService;
import com.xnx3.j2ee.util.ActionLogUtil;
import com.xnx3.j2ee.util.ConsoleUtil;
import com.xnx3.j2ee.util.Page;
import com.xnx3.j2ee.util.SpringUtil;
import com.xnx3.j2ee.util.Sql;
import com.xnx3.j2ee.vo.BaseVO;

import cn.zvo.translate.tcdn.admin.vo.TranslateSiteDomainListVO;
import cn.zvo.translate.tcdn.admin.vo.TranslateSiteDomainVO;
import cn.zvo.translate.tcdn.core.entity.TranslateSite;
import cn.zvo.translate.tcdn.core.entity.TranslateSiteDomain;
import cn.zvo.translate.tcdn.core.entity.TranslateSiteSet;
import cn.zvo.translate.tcdn.core.util.TranslateApiRequestUtil;
import cn.zvo.translate.tcdn.generate.Task;
import cn.zvo.translate.tcdn.generate.vo.WaitingProgressVO;

/**
 * 翻译站点绑定域名相关
 * @author <a href="https://github.com/xnx3/writecode">WriteCode自动生成</a>
 */
@Controller(value = "TranslateSiteDomainController")
@RequestMapping("/translate/mirrorimage/translateSiteDomain/")
public class TranslateSiteDomainController extends BaseController {

	@Resource
	private SqlService sqlService;
	@Resource
	private SqlCacheService sqlCacheService;
	
	
	/**
	 * 列表信息
	 * @param token 当前操作用户的登录标识
	 * 			<p>可通过 <a href="xxxxx.html">/xxxx/login.json</a> 取得</p>
	 * TODO [tag-3] 
	 * @param domain 搜索项，绑定的域名，比如 english.xxxxxx.com 
	 * @param language 搜索项，翻译语种，要翻译为的语种,该域名访问看到的语种。如 english ，跟 http://api.translate.zvo.cn/doc/language.json.html 这里的值对应 
	 * @param everyNumber 每页显示多少条数据。取值 1～100，
	 * 			<p>最大显示100条数据，若传入超过100，则只会返回100条<p>
	 * 			<p>若不传，默认显示15条</p>
	 * @param currentPage 获取第几页的数据。若不传，默认请求第一页的数据
	 * @return 若成功，则返回列表数据
	 * @author <a href="https://github.com/xnx3/writecode">WriteCode自动生成</a>
	 */
	@ResponseBody
	@RequestMapping(value = "list.json", method = {RequestMethod.POST})
	public TranslateSiteDomainListVO list(
			@RequestParam(value = "everyNumber", required = false, defaultValue = "15") int everyNumber,
			@RequestParam(value = "currentPage", required = false, defaultValue = "0") int currentPage,
			HttpServletRequest request) {

        /**
         * TODO 列表功能调整
         * 实体类 TranslateSiteDomain
         * 说明：
         * 	1.根据实际需求，设置WHERE条件
         *      * 使用 sql.appendWhere() 方法，设置各种WHERE条件
         *      * 例如：sql.appendWhere("id = 1");
         *      * 详见 tag-1
         * 	2.列表可以通过某些字段进行筛选
         * 		* 调整 sql.setSearchColumn() 方法的内容，将其中的字段进行删除或调整
         * 		* 调整参数注释中的内容
         *      * 详见 tag-2，tag-3
         * 	3.列表根据实际需求设置排序
         * 		* 使用 sql.setDefaultOrderBy() 方法，设置 sort 正序排序即可
         * 		* 详见 tag-4
         * 	4.根据实际需求，调整jsp页面内容
         * 		* 例如：删除不需要显示的字段；删除不需要筛选的字段。
         * 		* 页面位置：src/main/webapp/translate/mirrorimage/translateSiteDomain/list.jsp
         * 		* 详见页面中 tag-5，tag-6，tag-7
         * 	技术文档参考：
         * 		https://e.gitee.com/leimingyun/doc/share/8ca49d527b5f4403/?sub_id=3601239
         * 		https://gitee.com/leimingyun/wm/blob/master/src/main/java/com/xnx3/j2ee/util/Sql.java
         * 		https://gitee.com/leimingyun/wm/blob/master/src/main/java/com/xnx3/j2ee/util/Page.java
         */

		TranslateSiteDomainListVO vo = new TranslateSiteDomainListVO();

		// 创建Sql
		Sql sql = new Sql(request);
		// 配置查询那个表
		sql.setSearchTable("translate_site_domain");
		// TODO [tag-1] 增加更多查询条件
		sql.appendWhere("userid = " + getUserId());
		// TODO [tag-2] 查询条件-配置按某个字端搜索内容
		sql.setSearchColumn(new String[] {"domain", "language", "siteid"});
		// 查询数据表的记录总条数
		int count = sqlService.count("translate_site_domain", sql.getWhere());
		
		// 配置每页显示多少条，进行分页，取得分页信息
		Page page = new Page(count, everyNumber, request);
		// 查询出总页数
		sql.setSelectFromAndPage("SELECT * FROM translate_site_domain ", page);
		// TODO [tag-4] 选择排序方式 当用户没有选择排序方式时，系统默认 主键 ASC 排序
		//sql.setDefaultOrderBy("id DESC");
		
		// 按照上方条件查询出该实体总数 用集合来装
		List<TranslateSiteDomain> list = sqlService.findBySql(sql, TranslateSiteDomain.class);
		
		vo.setList(list);
		vo.setPage(page);
		
		// 日志记录
		ActionLogUtil.insert(request, "查看 翻译站点绑定域名相关 列表");
		
		return vo;
	}
	
	/**
	 * 获取某条的数据
	 * @param token 当前操作用户的登录标识 <required>
	 * 			<a href="xxxxx.html">/xxxx/login.json</a> 取得</p>
	 * @param id 主键
	 * @return 若成功，则可获取此条信息
	 * @author <a href="https://github.com/xnx3/writecode">WriteCode自动生成</a>
	 */
	@ResponseBody
	@RequestMapping(value = "details.json", method = {RequestMethod.POST})
	public TranslateSiteDomainVO details(HttpServletRequest request,
			@RequestParam(value = "id", required = false, defaultValue = "0") int id) {
		TranslateSiteDomainVO vo = new TranslateSiteDomainVO();

		if(id != 0) {
			TranslateSiteDomain entity = sqlService.findById(TranslateSiteDomain.class, id);
			if(entity == null){
				vo.setBaseVO(BaseVO.FAILURE, "要修改的信息不存在");
				return vo;
			}
			if(entity.getUserid() - getUserId() != 0) {
				vo.setBaseVO(BaseVO.FAILURE, "信息不属于您，无权操作");
				return vo;
			}
			vo.setTranslateSiteDomain(entity);
			ActionLogUtil.insert(request, "获取 translate_site_domain.id 为 " + id + " 的信息", entity.toString());
		}else {
			vo.setBaseVO(BaseVO.FAILURE, "请传入id");
			return vo;
		}
		
		return vo;
	}
	
	/**
	 * 添加或修改一条记录
	 * @param token 当前操作用户的登录标识 <required>
	 * 			<a href="xxxxx.html">/xxxx/login.json</a> 取得</p>
	 * TODO [tag-8] 
	 * @param id 对应 translateSite.id 
	 * @param domain 绑定的域名，比如 english.xxxxxx.com 
	 * @param language 翻译语种，要翻译为的语种,该域名访问看到的语种。如 english ，跟 http://api.translate.zvo.cn/doc/language.json.html 这里的值对应 
	 * @param siteid 域名所属的site站点，如果是新增，那这里要传入，表示新增的域名时属于哪个站点
	 * @return 保存结果
	 * @author <a href="https://github.com/xnx3/writecode">WriteCode自动生成</a>
	 */
	@ResponseBody
	@RequestMapping(value = "save.json", method = {RequestMethod.POST})
	public BaseVO save(
	        // TODO [tag-9]
			//@RequestParam(value = "id", required = false, defaultValue = "0") int id,
			@RequestParam(value = "id", required = false, defaultValue = "0") int id,
			@RequestParam(value = "domain", required = false, defaultValue = "") String domain,
			@RequestParam(value = "language", required = false, defaultValue = "") String language,
			@RequestParam(value = "siteid", required = false, defaultValue = "0") int siteid,
			HttpServletRequest request) {

        /**
         * TODO 添加编辑功能调整
         * 说明：
         * 	1.根据实际需求，调整要传递的参数，以及保存的数据
         * 		* 详见 tag-8，tag-9，tag-10
         * 	2.根据实际需求，在添加或编辑时，主动设置部分字段的值
         * 		* 例如：添加时设置创建时间 entity.setCreateTime(nowTime);
         *  3.根据实际需求，调整jsp页面内容
         *  	* 例如：删除不需要保存的字段；不能编辑的字段，将其input隐藏。
         *  	* 页面位置：src/main/webapp/translate/mirrorimage/translateSiteDomain/edit.jsp
         *  	* 详见页面中 tag-11
         */

		// 创建一个实体
		TranslateSiteDomain entity;
		if(id - 0 == 0) {
			// 添加
			entity = new TranslateSiteDomain();
			entity.setSiteid(siteid);
			entity.setUserid(getUserId());
		} else {
			// 修改
			entity = sqlService.findById(TranslateSiteDomain.class, id);
			if(entity == null) {
				return error("根据id，没查到该信息");
			}
			if(entity.getUserid() - getUserId() != 0) {
				return error("信息不属于您，无权操作");
			}
		}
		
		// TODO [tag-10] 给实体赋值 
		entity.setDomain(domain);
		entity.setLanguage(language);
		// 保存实体
		sqlService.save(entity);
		
		//删除缓存
		sqlCacheService.deleteCacheByProperty(TranslateSiteDomain.class, "domain", entity.getDomain());
		
		// 日志记录
		if(id - 0 == 0) {
			ActionLogUtil.insertUpdateDatabase(request, "向 translate_site_domain 新增一条记录", entity.toString());
		}else{
			ActionLogUtil.insertUpdateDatabase(request, "修改 translate_site_domain.id 为 " + id + " 的记录", entity.toString());
		}
		
		return success(entity.getId()+"");
	}
	

	/**
	 * 增加泛解析
	 * @param token 当前操作用户的登录标识 <required>
	 * 			<a href="xxxxx.html">/xxxx/login.json</a> 取得</p>
	 * TODO [tag-8] 
	 * @param id 对应 translateSite.id 
	 * @param domain 绑定的域名，比如 english.xxxxxx.com 
	 * @param language 翻译语种，要翻译为的语种,该域名访问看到的语种。如 english ，跟 http://api.translate.zvo.cn/doc/language.json.html 这里的值对应 
	 * @param siteid 域名所属的site站点，如果是新增，那这里要传入，表示新增的域名时属于哪个站点
	 * @return 保存结果
	 * @author <a href="https://github.com/xnx3/writecode">WriteCode自动生成</a>
	 */
	@ResponseBody
	@RequestMapping(value = "fanjiexi.json", method = {RequestMethod.POST})
	public BaseVO fanjiexi(
	        // TODO [tag-9]
			//@RequestParam(value = "id", required = false, defaultValue = "0") int id,
			@RequestParam(value = "id", required = false, defaultValue = "0") int id,
			@RequestParam(value = "domain", required = false, defaultValue = "") String domain,
			@RequestParam(value = "language", required = false, defaultValue = "") String language,
			@RequestParam(value = "siteid", required = false, defaultValue = "0") int siteid,
			HttpServletRequest request) {

        /**
         * TODO 添加编辑功能调整
         * 说明：
         * 	1.根据实际需求，调整要传递的参数，以及保存的数据
         * 		* 详见 tag-8，tag-9，tag-10
         * 	2.根据实际需求，在添加或编辑时，主动设置部分字段的值
         * 		* 例如：添加时设置创建时间 entity.setCreateTime(nowTime);
         *  3.根据实际需求，调整jsp页面内容
         *  	* 例如：删除不需要保存的字段；不能编辑的字段，将其input隐藏。
         *  	* 页面位置：src/main/webapp/translate/mirrorimage/translateSiteDomain/edit.jsp
         *  	* 详见页面中 tag-11
         */

		// 创建一个实体
		TranslateSiteDomain entity;
		if(id - 0 == 0) {
			// 添加
			entity = new TranslateSiteDomain();
			entity.setSiteid(siteid);
			entity.setUserid(getUserId());
		} else {
			// 修改
			entity = sqlService.findById(TranslateSiteDomain.class, id);
			if(entity == null) {
				return error("根据id，没查到该信息");
			}
			if(entity.getUserid() - getUserId() != 0) {
				return error("信息不属于您，无权操作");
			}
		}
		
		// TODO [tag-10] 给实体赋值 
		entity.setDomain(domain);
		entity.setLanguage(language);
		// 保存实体
		sqlService.save(entity);
		
		//删除缓存
		sqlCacheService.deleteCacheByProperty(TranslateSiteDomain.class, "domain", entity.getDomain());
		
		// 日志记录
		if(id - 0 == 0) {
			ActionLogUtil.insertUpdateDatabase(request, "向 translate_site_domain 新增一条记录", entity.toString());
		}else{
			ActionLogUtil.insertUpdateDatabase(request, "修改 translate_site_domain.id 为 " + id + " 的记录", entity.toString());
		}
		
		return success(entity.getId()+"");
	}
	
	
	/**
	 * 删除记录
	 * @param id 要删除的记录的id
	 * @param token 当前操作用户的登录标识 <required>
	 * 			<a href="xxxxx.html">/xxxx/login.json</a> 取得</p>
	 * @return 若成功，则可以删除成功
	 * @author <a href="https://github.com/xnx3/writecode">WriteCode自动生成</a>
	 */
	@ResponseBody
	@RequestMapping(value = "delete.json", method = {RequestMethod.POST})
	public BaseVO delete(HttpServletRequest request,
			@RequestParam(value = "id", required = false, defaultValue = "0") int id) {

		/**
         * TODO 删除功能调整
         * 说明：
         * 	1.当前删除使用的是物理删除，会将这条数据从数据库中删除掉，实际开发中不建议这样做，所以这里需要调整删除功能的逻辑，
         * 		将其改为逻辑删除，也就是通过某个字段的值，来记录该数据是否已删除。
         * 		* 将物理删除 sqlService.delete() 改为逻辑删除
         * 		  例如：
         *          - 将
         *          -   sqlService.delete(); // 物理删除，会从表中删除此条数据
         *          - 改为
         *          -   entity.setIsDelete(delete); // 逻辑删除，通过设置某字段状态实现
         *          -   sqlService.save(entity); // 保存实体
         *      * 详见 tag-12
         */
		/*
		 *
		 * 1. 这里是物理
		 * 2. 要判断是否具有删除权利
		 *
		 */
			
		if(id - 0 <= 0) {
			return error("请传入id");
		}
		
		TranslateSiteDomain entity = sqlService.findById(TranslateSiteDomain.class, id);
		if(entity == null) {
			return error("要删除的记录不存在");
		}
		if(entity.getUserid() - getUserId() != 0) {
			return error("信息不属于您，无权操作");
		}
		
		// TODO [tag-12] 现在是物理删除，改为逻辑删除
		sqlService.delete(entity);
		
		//删除缓存
		sqlCacheService.deleteCacheByProperty(TranslateSiteDomain.class, "domain", entity.getDomain());
		
		// 日志记录
		ActionLogUtil.insertUpdateDatabase(request, id, "删除 translate_site_domain.id 为 " + id + " 的记录", entity.toString());
		
		return success();
	}
	
	/**
	 * 清空缓存
	 * @param id
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value = "clearCache.json", method = {RequestMethod.POST})
	public BaseVO clearCache(HttpServletRequest request,
			@RequestParam(value = "id", required = false, defaultValue = "0") int id) {
		
		
		
		
		return success();
	}
	

	/**
	 * 生成整站html文件推送到指定存储
	 * @param id
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value = "generate.json", method = {RequestMethod.POST})
	public BaseVO generate(HttpServletRequest request,
			@RequestParam(value = "id", required = false, defaultValue = "0") int id) {
		if(id - 0 <= 0) {
			return error("请传入id");
		}
		
		TranslateSiteDomain entity = sqlService.findById(TranslateSiteDomain.class, id);
		if(entity == null) {
			return error("要删除的记录不存在");
		}
		if(entity.getUserid() - getUserId() != 0) {
			return error("信息不属于您，无权操作");
		}

		WaitingProgressVO waitVO = Task.waitingProgress(entity.getSiteid());
		if(waitVO.getRank() > -1) {
			return error("您当前有等待翻译的任务，请等待几分钟，您之前的任务执行完成后，再提交新任务");
		}
		
		TranslateSite site = sqlService.findById(TranslateSite.class, entity.getSiteid());
		
		List<TranslateSiteDomain> domainList = new ArrayList<TranslateSiteDomain>();
		domainList.add(entity);
		
		Task.add(site, domainList);
		Task.execute();
		
		return success();
	}
	

	/**
	 * 预览某个网页的翻译结果
	 * @param domainid translate_site_domain.id
	 * @param path 访问的path，不穿则是 / ，比如可以传入 a/b.html
	 */
	@RequestMapping(value="preview.do")
	@ResponseBody
	public String preview(HttpServletRequest request, HttpServletResponse response, Model model,
			@RequestParam(value = "domainid", required = false, defaultValue = "0") int domainid,
			@RequestParam(value = "path", required = false, defaultValue = "/") String path
		) throws IOException{
		
		//找到这个 site_domain
		if(domainid - 0 <= 0) {
			return "请传入domainid";
		}
		TranslateSiteDomain domain = sqlService.findById(TranslateSiteDomain.class, domainid);
		if(domain == null) {
			return "要删除的domain记录不存在";
		}
		if(domain.getUserid() - getUserId() != 0) {
			return "信息不属于您，无权操作";
		}
		
		//找到源站
		TranslateSite site = sqlService.findById(TranslateSite.class, domain.getSiteid());
		if(site == null) {
			return "源站点未发现";
		}
		
		//网站本身的语种
		String localLanguage = site.getLanguage();
		//当前访问的域名要以什么语种显示出来
		String targetLanguage = domain.getLanguage();
		
		String sourceDomain = site.getUrl(); //源站点，格式如 "http://www.zbyjzb.com"
		String newDomain = domain.getDomain();
		
		Log.info("当前访问域名："+newDomain+", 源站："+sourceDomain+", 将 "+localLanguage+"转为"+targetLanguage);
		
		String html;
		long startTime = DateUtil.timeForUnix13();
		
		//获取站点设置相关
		TranslateSiteSet siteSet = sqlService.findById(TranslateSiteSet.class, site.getId());
		if(siteSet == null) {
			siteSet = new TranslateSiteSet();
		}
		
		com.xnx3.BaseVO tvo = TranslateApiRequestUtil.trans(sourceDomain, newDomain, sourceDomain+path, "false",targetLanguage, siteSet.getExecuteJs(), request);
		if(tvo.getResult() - BaseVO.FAILURE == 0) {
			//出错
			response.setStatus(500);
			return tvo.getInfo();
		}
		
		/*** 正常 ***/
		html = tvo.getInfo();
		
		long endTime = DateUtil.timeForUnix13();
		Log.info("time : "+(endTime-startTime)+"mm");
		
		//增加 htmlAppendJs
		if(siteSet.getHtmlAppendJs().length() > 0) {
			html = html + siteSet.getHtmlAppendJs();
		}
		return html;
	}
}